<?php

declare(strict_types=1);

namespace app\model\oa;

use think\Model;

/**
 * 定时任务模型
 * @package app\model\oa
 */
class TimingTask extends Model
{
    /**
     * 表名（不含前缀）
     * @var string
     */
    protected $name = 'timing_task';

    /**
     * 主键
     * @var string
     */
    protected $pk = 'id';

    /**
     * 自动时间戳
     * @var bool
     */
    protected $autoWriteTimestamp = false;

    /**
     * 创建时间字段
     * @var string
     */
    protected $createTime = 'create_time';

    /**
     * 更新时间字段
     * @var string
     */
    protected $updateTime = 'update_time';

    /**
     * 软删除字段
     * @var string
     */
    protected $deleteTime = 'delete_time';

    /**
     * 任务类型常量
     */
    const TYPE_SYSTEM = 1;   // 系统任务
    const TYPE_NORMAL = 2;   // 普通任务
    const TYPE_CUSTOM = 3;   // 自定义任务

    /**
     * 字段类型映射
     * @var array
     */
    protected $schema = [
        'id' => 'int',
        'title' => 'string',
        'name' => 'string',
        'link' => 'string',
        'types' => 'int',
        'desc' => 'string',
        'create_time' => 'int',
        'update_time' => 'int',
        'delete_time' => 'int',
    ];

    /**
     * 获取任务类型列表
     * @return array
     */
    public static function getTaskTypes(): array
    {
        return [
            self::TYPE_SYSTEM => '系统任务',
            self::TYPE_NORMAL => '普通任务',
            self::TYPE_CUSTOM => '自定义任务',
        ];
    }

    /**
     * 获取所有任务
     * @return \think\model\Collection
     */
    public static function getAllTasks()
    {
        return self::order('id', 'desc')->select();
    }

    /**
     * 根据类型获取任务
     * @param int $type
     * @return \think\model\Collection
     */
    public static function getByType(int $type)
    {
        return self::where('types', $type)
            ->order('id', 'desc')
            ->select();
    }

    /**
     * 根据名称获取任务
     * @param string $name
     * @return \think\Model|null
     */
    public static function getByName(string $name)
    {
        return self::where('name', $name)->find();
    }

    /**
     * 任务类型描述获取器
     * @param int $value
     * @return string
     */
    public function getTypeTextAttr(int $value): string
    {
        $typeMap = self::getTaskTypes();
        return $typeMap[$value] ?? '未知';
    }

    /**
     * 任务类型搜索器
     * @param \think\db\Query $query
     * @param mixed $value
     */
    public function searchTypeAttr($query, $value)
    {
        if ($value !== '') {
            $query->where('types', $value);
        }
    }

    /**
     * 标题搜索器
     * @param \think\db\Query $query
     * @param mixed $value
     */
    public function searchTitleAttr($query, $value)
    {
        if ($value !== '') {
            $query->whereLike('title', '%' . $value . '%');
        }
    }

    /**
     * 名称搜索器
     * @param \think\db\Query $query
     * @param mixed $value
     */
    public function searchNameAttr($query, $value)
    {
        if ($value !== '') {
            $query->whereLike('name', '%' . $value . '%');
        }
    }

    /**
     * 描述搜索器
     * @param \think\db\Query $query
     * @param mixed $value
     */
    public function searchDescAttr($query, $value)
    {
        if ($value !== '') {
            $query->whereLike('desc', '%' . $value . '%');
        }
    }

    /**
     * 创建时间范围搜索器
     * @param \think\db\Query $query
     * @param array $value
     */
    public function searchCreateTimeAttr($query, array $value)
    {
        if (!empty($value[0])) {
            $query->where('create_time', '>=', strtotime($value[0]));
        }
        if (!empty($value[1])) {
            $query->where('create_time', '<=', strtotime($value[1]));
        }
    }

    /**
     * 验证任务名称是否唯一
     * @param string $name
     * @param int|null $excludeId
     * @return bool
     */
    public static function isNameUnique(string $name, ?int $excludeId = null): bool
    {
        $query = self::where('name', $name);
        
        if ($excludeId !== null) {
            $query->where('id', '<>', $excludeId);
        }
        
        return $query->count() === 0;
    }

    /**
     * 获取系统任务
     * @return \think\model\Collection
     */
    public static function getSystemTasks()
    {
        return self::where('types', self::TYPE_SYSTEM)
            ->order('id', 'asc')
            ->select();
    }

    /**
     * 获取自定义任务
     * @return \think\model\Collection
     */
    public static function getCustomTasks()
    {
        return self::where('types', self::TYPE_CUSTOM)
            ->order('id', 'desc')
            ->select();
    }

    /**
     * 获取任务执行链接
     * @return string
     */
    public function getExecuteUrl(): string
    {
        return $this->link ?? '';
    }

    /**
     * 获取任务描述
     * @return string
     */
    public function getDescription(): string
    {
        return $this->desc ?? '';
    }

    /**
     * 判断是否为系统任务
     * @return bool
     */
    public function isSystemTask(): bool
    {
        return $this->types === self::TYPE_SYSTEM;
    }

    /**
     * 判断是否为普通任务
     * @return bool
     */
    public function isNormalTask(): bool
    {
        return $this->types === self::TYPE_NORMAL;
    }

    /**
     * 判断是否为自定义任务
     * @return bool
     */
    public function isCustomTask(): bool
    {
        return $this->types === self::TYPE_CUSTOM;
    }

    /**
     * 获取任务统计
     * @return array
     */
    public static function getTaskStats(): array
    {
        $stats = self::field('types, COUNT(*) as count')
            ->group('types')
            ->select()
            ->toArray();

        $result = [
            self::TYPE_SYSTEM => 0,
            self::TYPE_NORMAL => 0,
            self::TYPE_CUSTOM => 0,
            'total' => 0,
        ];

        foreach ($stats as $stat) {
            if (isset($result[$stat['types']])) {
                $result[$stat['types']] = (int)$stat['count'];
                $result['total'] += (int)$stat['count'];
            }
        }

        return $result;
    }
}